<?php
/*	Copyright © 2007-2008 Patrick Palka
	
	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.*/
class STemplate {
	const VERSION = '1.1';
	protected $file, $data = array();

	function __construct($file) {
		$this->file = $file;
	}

	function &get($name) {
		return $this->data[$name];
	}

	function set($name, $value = null) {
		if(is_array($name)) {
			foreach($name as $_name => $_value) {
				$this->{__FUNCTION__}($_name, $_value);
			}
		} else {
			$name =& $this->get($name);
			$name = $value;
		}
	}

	function stem($name, $file) {
		$template = new self($file);
		$this->set($name, $template);
		return $template;
	}
}

class STemplator extends STemplate {
	private $transformers;
	private static $dir = '', $ext = '';

	function __construct($file) {
		parent::__construct($file);
		$this->addDataTransformer(get_parent_class(), array($this, 'cb_transform_parent'));
	}
	
	static function setPath($dir, $ext = null) {
		self::$dir = $dir;
		if($ext) {
			self::$ext = $ext;
		}
	}

	private function load(parent $template) {
		array_walk($template->data, array($this, 'transform'));
		extract($template->data);
		require self::$dir . $template->file . self::$ext;
	}
	
	function output() {
		$this->load($this);
	}

	private function transform(&$data) {
		if(is_object($data)) {
			for($classes = array(get_class($data)); $parent_class = get_parent_class(end($classes)); $classes[] = $parent_class);
			foreach($classes as $class) {
				if(isset($this->transformers[$class])) {
					$data = call_user_func($this->transformers[$class], $data);
				}
			}
		}
	}

	function addDataTransformer($class, $callback) {
		if(is_object($class)) {
			$class = get_class($class);
		}
		$this->transformers[$class] = $callback;
	}

	private function cb_transform_parent($template) {
		ob_start();
		$this->load($template);
		return ob_get_clean();
	}
}

STemplator::setPath('templates/', '.php');
$tpl = new STemplator('master');
	$tpl->set(array('title' => 'hi', 'year' => 2008));
	$tpl->stem('content', 'topiclist')->set('topic_title', 'test topic title');
$tpl->output();